home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / COMPILER / SATHER / !Sather / Library / Graphs / sa / digrph_vws < prev    next >
Text File  |  1996-07-13  |  12KB  |  340 lines

  1. ---------------------------> Sather 1.1 source file <--------------------------
  2. -- Author: Benedict A. Gomes <gomes@icsi.berkeley.edu>
  3. -- Copyright (C) 1995, International Computer Science Institute
  4. -- COPYRIGHT NOTICE: This code is provided WITHOUT ANY WARRANTY
  5. -- and is subject to the terms of the SATHER LIBRARY GENERAL PUBLIC
  6. -- LICENSE contained in the file: Sather/Doc/License of the
  7. -- Sather distribution. The license is also available from ICSI,
  8. -- 1947 Center St., Suite 600, Berkeley CA 94704, USA.
  9. -------------------------------------------------------------------
  10. -- Design Note:
  11. --  It might be useful to have versions of these views which are
  12. --  pre-parametrized over $RO_DIGRAPH or $DIGRAPH for convenience
  13. --  These have been written and could be added, but it is not
  14. --  clear whether they help just confuse matters
  15. -------------------------------------------------------------------
  16. class DIGRAPH_NODE_SET_VIEW{NTP,GTP<$RO_DIGRAPH{NTP}} < $RO_SET{NTP} is
  17.    -- A view of the nodes of a digraph as a set. This is useful for
  18.    -- looking at set properties of the nodes in the graph, for instance,
  19.    -- finding the union or intersection of the nodes in two graphs
  20.    -- Please see the notes in the module file
  21.    
  22.    include RO_SET_INCL{NTP};
  23.    
  24.    private attr graph: GTP;
  25.    
  26.    create(g: GTP): SAME is   res::=new; res.graph:=g; return res; end;
  27.    -- Create a new view of the nodes of "g"
  28.    
  29.    copy: SAME is
  30.       -- Return a copy of the nodes in this set
  31.       return #SAME(graph);
  32.    end;
  33.    
  34.    has(n: NTP): BOOL is return graph.has_node(n) end;
  35.    -- Return true if the original graph has the node "n"
  36.    
  37.    size: INT is return graph.n_nodes end;
  38.    -- Return the number of nodes in the orignal graph
  39.    
  40.    elt!: NTP is loop yield graph.node! end; end;
  41.    -- Return the nodes of the original graph
  42.    
  43. end;
  44. -------------------------------------------------------------------
  45. class DIGRAPH_EDGE_SET_VIEW{NTP,GTP<$RO_DIGRAPH{NTP}} < $RO_SET{DIEDGE{NTP}} is
  46.    -- View of the edges of a graph as a read-only set.
  47.    -- Design Note:
  48.    -- Letting this set be writable is interesting, but can lead to
  49.    -- very confusing results due to aliasing.
  50.    include RO_SET_INCL{DIEDGE{NTP}};
  51.    
  52.    private attr graph: GTP;
  53.    -- Holds a pointer to the actual graph being viewed
  54.    
  55.    create(g: GTP): SAME is   res::=new;res.graph:=g;return res; end;
  56.    -- Create a view of the set of edges of the digraph "g"
  57.    
  58.    has(e: DIEDGE{NTP}): BOOL is return graph.has_edge(e) end;
  59.    -- Return true if the digraph contains the edge "e"
  60.    
  61.    size: INT is return graph.n_edges end;
  62.    -- Returns the number of edges in the digraph
  63.    
  64.    elt!: DIEDGE{NTP} is loop yield graph.edge! end; end;
  65.    -- Yields the edges of the digraph
  66.    
  67.    copy: SAME is return #(graph) end;
  68.    -- Returns a copy of the original digraph
  69.    
  70. end;
  71. -------------------------------------------------------------------
  72. class DIGRAPH_INC_SET_VIEW{NTP,GTP<$DIGRAPH{NTP}} < $RO_SET{NTP} is
  73.    -- View of the incoming edges into the node of a digraph. 
  74.  
  75.    include RO_SET_INCL{NTP} has->, elt!->;
  76.    
  77.    private attr graph: GTP;
  78.    -- A pointer to the original graph being viewed
  79.    private attr dest: NTP;
  80.    -- The node whose incoming edges are being viewed
  81.    
  82.    create(g: GTP,dest: NTP): SAME is 
  83.       -- Create a view of the set of incoming nodes to "dest" in the
  84.       -- graph "g"
  85.       res ::= new; res.graph := g; res.dest := dest;   return  res;
  86.    end;
  87.    
  88.    has(n: NTP): BOOL is return graph.has_edge(#DIEDGE{NTP}(n,dest)) end;
  89.    -- Return true if node "dest" has an incoming edge from "n"
  90.    
  91.    size: INT is return graph.n_incoming(dest) end;
  92.    -- Return the number of incoming edges into "dest"
  93.    
  94.    elt!: NTP is loop yield graph.incoming!(dest) end; end;
  95.    -- Yield the nodes which have edges to "dest"
  96.    
  97.    copy: SAME is return #(graph,dest) end;
  98.    -- Return a copy of self
  99.    
  100. end;
  101. -------------------------------------------------------------------
  102. class DIGRAPH_OUTG_SET_VIEW{NTP,GTP<$RO_DIGRAPH{NTP}} < $RO_SET{NTP} is
  103.    -- View of the outgoing edges into the node of a digraph. 
  104.    include RO_SET_INCL{NTP}; 
  105.    
  106.    private attr graph: GTP;
  107.    -- The graph being viewed
  108.    private attr src: NTP;
  109.    -- The node whose outgoing edges are being viewed
  110.    
  111.    create(g:GTP, src: NTP): SAME is return new.init(g,src);  end;
  112.    
  113.    private init(g: GTP,s: NTP): SAME is 
  114.       graph := g; src:=s; return self
  115.    end;
  116.    
  117.    has(n: NTP): BOOL is return graph.has_edge(#DIEDGE{NTP}(src,n)) end;
  118.    
  119.    size: INT is return graph.n_outgoing(src) end;
  120.    
  121.    elt!: NTP is loop yield graph.outgoing!(src) end; end;
  122.    
  123.    copy: SAME is return #(graph,src) end;
  124.    -- Return a copy of self
  125.  
  126. end;
  127. -------------------------------------------------------------------
  128. class DIGRAPH_REV_DIGRAPH_VIEW{NTP,GTP<$DIGRAPH{NTP}} < $DIGRAPH{NTP} is
  129.    -- A view of a digraph with all edges reversed.  Unlike most other
  130.    -- views, this view of the graph permits modification operations,
  131.    -- which are translated into operations on the original graph.
  132.    -- Care should be taken in operations that involved both the
  133.    -- original graph and this view
  134.   
  135.    include DIGRAPH_INCL{NTP};
  136.    
  137.    private attr source:GTP;
  138.    
  139.    create(m:GTP): SAME is
  140.       -- Create a subgraph of "m"
  141.       res ::= new;
  142.       res.source := m;
  143.       return(res);
  144.    end;
  145.  
  146.    add_node: NTP is return source.add_node end;
  147.    
  148.    add_node(n: NTP): NTP is   return source.add_node(n);  end;
  149.    
  150.    connect(e: DIEDGE{NTP}) is  source.connect(e.reverse);  end;
  151.    
  152.    delete_node(n: NTP) is source.delete_node(n) end;
  153.    
  154.    disconnect(e: DIEDGE{NTP}) is source.disconnect(e.reverse) end;
  155.    
  156.    has_node(n: NTP): BOOL is return source.has_node(n) end;
  157.    
  158.    has_edge(e: DIEDGE{NTP}): BOOL is return source.has_edge(e.reverse) end;
  159.    
  160.    n_edges: INT is
  161.       i ::= 0;  loop n ::= node!; i := i +  n_incoming(n); end;
  162.       return i;
  163.    end;
  164.    
  165.    n_nodes: INT is return(source.n_nodes) end;
  166.  
  167.    n_incoming(n: NTP): INT is return source.n_outgoing(n) end;
  168.    
  169.    n_outgoing(n: NTP): INT is return source.n_incoming(n) end;
  170.    
  171.    node!: NTP is loop yield source.node! end; end;
  172.  
  173.    edge!: DIEDGE{NTP} is 
  174.       loop n ::= node!;
  175.      loop inc::= incoming!(n); yield #DIEDGE{NTP}(inc,n); end;
  176.       end;
  177.    end;
  178.    
  179.    incoming!(once n: NTP): NTP is loop yield source.outgoing!(n) end; end;
  180.    
  181.    outgoing!(once n: NTP): NTP is loop yield source.incoming!(n) end; end;
  182.  
  183. end;
  184. -------------------------------------------------------------------
  185. class FILTERGRAPH_DIGRAPH_VIEW{NTP,GTP<$RO_DIGRAPH{NTP}} < $RO_DIGRAPH{NTP} is
  186.    -- View a graph through a node/edge filter predicate
  187.    -- Only the nodes and edges that satisfy the predicates are visible
  188.    -- as nodes and edges in this view.
  189.    -- If the node predicate is "np" and the edge predicate is "ep",
  190.    -- Nodes which satisfy "np" are in the graph
  191.    -- Edges which satisfy "ep" and whose nodes are both satisfied by
  192.    -- "np" are in the graph.
  193.  
  194.    
  195.    include RO_DIGRAPH_INCL{NTP};
  196.    
  197.    private attr source:GTP;
  198.    private attr np: ROUT{NTP}: BOOL;
  199.    private attr ep: ROUT{DIEDGE{NTP}}: BOOL;
  200.    
  201.    create(m:GTP,np:ROUT{NTP}:BOOL,ep:ROUT{DIEDGE{NTP}}:BOOL): SAME
  202.    -- Create a subgraph of "m". It consists of nodes that pass the
  203.    -- node filter "np"  and edges that pass the edge filter,
  204.    -- whose ends pass the node filter.
  205.    -- Nodes n that belong to "m" and np.call(n) = true
  206.    -- Edges e (1) m.has_edge(e)
  207.    --         (2) np.call(e.first) and np.call(e.second)
  208.    --         (3) ep.call(e)
  209.    is
  210.       res ::= new;
  211.       res.source := m;
  212.       res.np := np;
  213.       res.ep := ep;
  214.       return(res);
  215.    end;
  216.    
  217.    create(m:GTP,np:ROUT{NTP}:BOOL): SAME is
  218.       -- Create a subgraph of "m", which includes all nodes that pass
  219.       -- the node filter "np"
  220.       res ::= new;
  221.       res.source := m;
  222.       res.np := np;
  223.       res.ep := void;
  224.       return(res);
  225.    end;
  226.    
  227.    has_node(n: NTP): BOOL is return source.has_node(n) and np.call(n)  end;
  228.    
  229.    has_edge(e: DIEDGE{NTP}): BOOL is 
  230.       -- An edge exists here if and only if it exists in the source,
  231.       -- both its end points pass the node filter and the edge itself
  232.       -- passes the edge filter
  233.       ef ::= e.first; es ::= e.second;
  234.       if void(ep) then
  235.      return source.has_edge(e) and np.call(ef) and np.call(es);
  236.       else
  237.      return source.has_edge(e) and np.call(ef) and np.call(es) and
  238.            ep.call(e)
  239.       end;
  240.    end;
  241.    
  242.    n_nodes: INT is 
  243.       i ::= 0; loop n ::= node!; i := i + 1; end;   return i;  
  244.    end;
  245.  
  246.    n_edges: INT is
  247.       i ::= 0;  loop n ::= node!; i := i +  n_incoming(n); end;
  248.       return i;
  249.    end;
  250.      
  251.    n_incoming(n: NTP): INT is 
  252.       -- Compute the number of edges by actually iterating over the
  253.       -- edges and returning the resulting number found
  254.       i ::= 0; loop discard ::= incoming!(n); i := i + 1; end;
  255.       return i;
  256.    end;
  257.  
  258.    n_outgoing(n: NTP): INT is 
  259.       -- Compute the number of outgoing edges by actually iterating over them
  260.       i ::= 0; loop discard ::= outgoing!(n); i := i + 1; end;
  261.       return i;
  262.    end;
  263.  
  264.    node!: NTP is 
  265.       -- Yield all the nodes in the source that pass the filter node predicate
  266.       loop n ::= source.node!;  if np.call(n) then yield n end;  end;
  267.    end;
  268.    
  269.    edge!: DIEDGE{NTP} is 
  270.       loop n ::= node!;
  271.      loop inc::= incoming!(n); yield #DIEDGE{NTP}(inc,n); end;
  272.       end;
  273.    end;
  274.  
  275.    incoming!(once n: NTP): NTP 
  276.       pre has_node(n) 
  277.       post has_edge(#DIEDGE{NTP}(n,result))
  278.    -- Yield all the incoming nodes from node "n". Yield only nodes
  279.    -- which pass the filter and are connected by an edge that passes the filter
  280.    is 
  281.       loop inc ::= source.incoming!(n); 
  282.      if np.call(inc) and ep.call(#DIEDGE{NTP}(inc,n)) then yield inc end;
  283.       end; 
  284.    end;
  285.    
  286.    outgoing!(once n: NTP): NTP 
  287.    -- Yield all the outgoing nodes from node "n". Yield only nodes
  288.    -- which pass the filter and are connected by an edge that passes the filter
  289.       pre has_node(n)
  290.       post has_edge(#DIEDGE{NTP}(n,result))
  291.    is 
  292.       loop og ::= source.outgoing!(n); 
  293.      if np.call(og) and ep.call(#DIEDGE{NTP}(n,og)) then yield og end;
  294.       end; 
  295.    end;
  296.    
  297. end;
  298. -------------------------------------------------------------------
  299. -- Note:
  300. -- Simplifications of corresponding class with the graph argument
  301. -- where the graph is assumed to be a generic $RO_DIGRAPH
  302. -- This version is convenient to use but may be considerably less
  303. -- efficient than the version with 2 parameters.
  304. -- If the type of the graph is known, the parametrized version
  305. -- has a strongly typed pointer to the actual graph, allowing
  306. -- many optimizations such as inlining, in addition to avoiding
  307. -- dispatching
  308. -------------------------------------------------------------------
  309. class DIGRAPH_NODE_SET_VIEW{NTP} < $RO_SET{NTP} is
  310.    -- Simplification of DIGRAPH_NODE_SET_VIEW which has a pointer
  311.    -- to a generic $DIGRAPH{NTP}. Less efficient
  312.    include DIGRAPH_NODE_SET_VIEW{NTP,$RO_DIGRAPH{NTP}};
  313. end;
  314. -------------------------------------------------------------------
  315. class DIGRAPH_EDGE_SET_VIEW{NTP} < $RO_SET{DIEDGE{NTP}} is
  316.    -- Simplification of DIGRAPH_EDGE_SET_VIEW with 2 parameters
  317.    include DIGRAPH_EDGE_SET_VIEW{NTP,$RO_DIGRAPH{NTP}};
  318. end;
  319. -------------------------------------------------------------------
  320. class DIGRAPH_INC_SET_VIEW{NTP} < $RO_SET{NTP} is
  321.    -- Simplification of DIGRAPH_INC_SET_VIEW with 2 parameters
  322.    include DIGRAPH_INC_SET_VIEW{NTP,$RO_DIGRAPH{NTP}};
  323. end;
  324. -------------------------------------------------------------------
  325. class DIGRAPH_OUTG_SET_VIEW{NTP} < $RO_SET{NTP} is
  326.    -- Simplification of DIGRAPH_OUTG_SET_VIEW with 2 parameters
  327.    include DIGRAPH_OUTG_SET_VIEW{NTP,$RO_DIGRAPH{NTP}};
  328. end;
  329. -------------------------------------------------------------------
  330. class FILTERGRAPH_DIGRAPH_VIEW{NTP} < $RO_DIGRAPH{NTP} is
  331.    -- Simplification of FILTERGRAPH_DIGRAPH_VIEW
  332.    include FILTERGRAPH_DIGRAPH_VIEW{NTP,$RO_DIGRAPH{NTP}};
  333. end;
  334. -------------------------------------------------------------------
  335. class DIGRAPH_REV_DIGRAPH_VIEW{NTP} < $DIGRAPH{NTP} is
  336.    -- Simplification of DIGRAPH_REV_DIGRAPH_VIEW
  337.    include DIGRAPH_REV_DIGRAPH_VIEW{NTP,$DIGRAPH{NTP}};
  338. end;
  339. -------------------------------------------------------------------
  340.